import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr'
import { API_CONFIG } from '@/config/api'

export class SocketService {
  constructor() {
    this.connection = null
    this.isConnected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 1000
    this.eventHandlers = new Map()
    this.connectionPromise = null
  }

  // 连接到SignalR Hub
  async connect(url = API_CONFIG.SIGNALR_URL) {
    if (this.connectionPromise) {
      return this.connectionPromise
    }

    this.connectionPromise = new Promise((resolve, reject) => {
      const connectAsync = async () => {
        try {
          console.log('正在连接SignalR:', url)
          
          this.connection = new HubConnectionBuilder()
            .withUrl(url)
            .withAutomaticReconnect([0, 2000, 10000, 30000])
            .configureLogging(LogLevel.Information)
            .build()

          // 设置事件处理器
          this.setupEventHandlers()

          // 启动连接
          await this.connection.start()
          this.isConnected = true
          this.reconnectAttempts = 0
          console.log('SignalR连接成功，连接状态:', this.connection.state)

          // 设置连接状态监听
          this.connection.onreconnecting(() => {
            console.log('SignalR重新连接中...')
            this.isConnected = false
          })

          this.connection.onreconnected(() => {
            console.log('SignalR重新连接成功')
            this.isConnected = true
          })

          this.connection.onclose(() => {
            console.log('SignalR连接关闭')
            this.isConnected = false
            this.connectionPromise = null
          })

          resolve()
        } catch (error) {
          console.error('SignalR连接失败:', error)
          this.connectionPromise = null
          reject(error)
        }
      }

      connectAsync()
    })

    return this.connectionPromise
  }

  // 断开连接
  async disconnect() {
    if (this.connection) {
      try {
        await this.connection.stop()
        this.connection = null
        this.isConnected = false
        this.connectionPromise = null
        console.log('SignalR连接已断开')
      } catch (error) {
        console.error('断开SignalR连接失败:', error)
      }
    }
  }

  // 设置事件处理器
  setupEventHandlers() {
    if (!this.connection) return

    // 房间相关事件
    this.connection.on('PlayerJoined', (player) => {
      console.log('收到PlayerJoined事件:', player)
      this.emit('playerJoined', player)
    })

    this.connection.on('PlayerLeft', (playerId) => {
      console.log('收到PlayerLeft事件:', playerId)
      this.emit('playerLeft', playerId)
    })

    this.connection.on('PlayerReady', (playerId, isReady) => {
      console.log('收到PlayerReady事件:', playerId, isReady)
      this.emit('playerReady', playerId, isReady)
    })

    this.connection.on('GameJoined', (game) => {
      console.log('收到GameJoined事件:', game)
      this.emit('gameJoined', game)
    })

    this.connection.on('RoomUpdated', (room) => {
      console.log('收到RoomUpdated事件:', room)
      this.emit('roomUpdated', room)
    })

    // 游戏相关事件
    this.connection.on('GameStarted', (gameData) => {
      console.log('收到GameStarted事件:', gameData)
      this.emit('gameStarted', gameData)
    })

    this.connection.on('GameEnded', (gameResult) => {
      console.log('收到GameEnded事件:', gameResult)
      this.emit('gameEnded', gameResult)
    })

    this.connection.on('PaintActionReceived', (paintAction) => {
      console.log('收到PaintActionReceived事件:', paintAction)
      this.emit('paintAction', paintAction)
    })

    this.connection.on('GameTimeUpdate', (timeRemaining) => {
      console.log('收到GameTimeUpdate事件:', timeRemaining)
      this.emit('gameTimeUpdate', timeRemaining)
    })

    // 系统事件
    this.connection.on('Error', (error) => {
      console.error('收到Error事件:', error)
      this.emit('error', error)
    })

    this.connection.on('Info', (message) => {
      console.log('收到Info事件:', message)
      this.emit('info', message)
    })
  }

  // 加入房间
  async joinRoom(roomId, playerData, password = null) {
    if (!(await this.ensureConnected())) {
      throw new Error('无法连接到服务器')
    }

    try {
      console.log('调用JoinGame:', roomId, playerData.nickName, password)
      await this.connection.invoke('JoinGame', roomId, playerData.nickName, password)
      console.log('已加入房间:', roomId)
    } catch (error) {
      console.error('加入房间失败:', error)
      throw error
    }
  }

  // 离开房间
  async leaveRoom(roomId, playerId) {
    if (!(await this.ensureConnected())) {
      return
    }

    try {
      await this.connection.invoke('LeaveGame', roomId, playerId)
      console.log('已离开房间:', roomId)
    } catch (error) {
      console.error('离开房间失败:', error)
    }
  }

  // 设置准备状态
  async setReady(roomId, playerId, isReady) {
    if (!(await this.ensureConnected())) {
      throw new Error('无法连接到服务器')
    }

    try {
      console.log('调用SetReady:', roomId, playerId, isReady)
      await this.connection.invoke('SetReady', roomId, playerId, isReady)
      console.log('设置准备状态成功:', isReady)
    } catch (error) {
      console.error('设置准备状态失败:', error)
      throw error
    }
  }

  // 开始游戏
  async startGame(roomId, playerId) {
    if (!(await this.ensureConnected())) {
      throw new Error('无法连接到服务器')
    }

    try {
      console.log('调用StartGame:', roomId, playerId)
      await this.connection.invoke('StartGame', roomId, playerId)
      console.log('游戏开始:', roomId)
    } catch (error) {
      console.error('开始游戏失败:', error)
      throw error
    }
  }

  // 提交涂色动作
  async submitPaintAction(roomId, playerId, x, y, brushSize) {
    if (!(await this.ensureConnected())) {
      throw new Error('无法连接到服务器')
    }

    try {
      console.log('Socket提交涂色动作:', {
        roomId,
        playerId,
        x,
        y,
        brushSize
      })
      
      await this.connection.invoke('PaintAction', roomId, playerId, x, y, brushSize)
      console.log('涂色动作提交成功')
    } catch (error) {
      console.error('提交涂色动作失败:', error)
      throw error
    }
  }

  // 踢出玩家
  async kickPlayer(roomId, playerId, targetPlayerId) {
    if (!(await this.ensureConnected())) {
      throw new Error('无法连接到服务器')
    }

    try {
      await this.connection.invoke('KickPlayer', roomId, playerId, targetPlayerId)
    } catch (error) {
      console.error('踢出玩家失败:', error)
      throw error
    }
  }

  // 事件监听
  on(event, handler) {
    if (!this.eventHandlers.has(event)) {
      this.eventHandlers.set(event, [])
    }
    this.eventHandlers.get(event).push(handler)
  }

  // 移除事件监听
  off(event, handler) {
    if (this.eventHandlers.has(event)) {
      const handlers = this.eventHandlers.get(event)
      const index = handlers.indexOf(handler)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    }
  }

  // 触发事件
  emit(event, ...args) {
    if (this.eventHandlers.has(event)) {
      const handlers = this.eventHandlers.get(event)
      handlers.forEach(handler => {
        try {
          handler(...args)
        } catch (error) {
          console.error(`事件处理器错误 [${event}]:`, error)
        }
      })
    }
  }

  // 获取连接状态
  getConnectionState() {
    if (!this.connection) return 'Disconnected'
    return this.connection.state
  }

  // 检查是否已连接
  getIsConnected() {
    const connectionState = this.connection?.state
    // 修复连接状态检查逻辑：只要connection存在且状态为Connected就认为已连接
    const isConnected = this.connection && connectionState === 'Connected'
    
    // 如果连接状态不正确，尝试更新内部状态
    if (this.isConnected !== isConnected) {
      this.isConnected = isConnected
      console.log('连接状态已更新:', isConnected)
    }
    
    console.log('连接状态检查:', {
      isConnected: this.isConnected,
      connectionState: connectionState,
      connectionExists: !!this.connection,
      result: isConnected
    })
    return isConnected
  }

  // 确保连接可用
  async ensureConnected() {
    if (!this.getIsConnected()) {
      console.log('连接不可用，尝试重新连接...')
      try {
        await this.connect()
        return true
      } catch (error) {
        console.error('重新连接失败:', error)
        return false
      }
    }
    return true
  }
}

// 根据环境选择服务 - 强制使用真实服务以获取后端数据
export const socketService = new SocketService()